﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Controls;

using Microsoft.VisualStudio.Shell.Interop;

using VSTalk.Engine;
using VSTalk.Engine.Core.EnvironmentManagers.UI;

namespace Microsoft.VSTalk.Integration
{
    public class EnvWindowsManager : IEnvWindowsManager
    {
        private readonly VSTalkPackage _package;

        private static IWindowManager WndManager
        {
            get { return AppServices.Get<IWindowManager>(); }
        }

        public EnvWindowsManager(VSTalkPackage package)
        {
            _package = package;
        }

        internal void SearchContent(BaseToolWindow toolWindow)
        {
            var availableControls = WndManager.HostedControls.All;
            foreach (var hostedControl in availableControls)
            {
                var window = _package.FindToolWindow(typeof(BaseToolWindow),
                    Math.Abs(hostedControl.GetType().ToString().GetHashCode()),
                    false);
                if (window == toolWindow)
                {
                    toolWindow.SetContent(hostedControl);
                    return;
                }
            }
        }

        public void ShowNestedWindow(UserControl userControl)
        {
            var window = _package.FindToolWindow(typeof(BaseToolWindow), 
                                                      Math.Abs(userControl.GetType().ToString().GetHashCode()), 
                                                      true);
            
            if (window == null || window.Frame == null)
            {
                throw new NotSupportedException(Resources.CanNotCreateWindow);
            }

            ((BaseToolWindow)window).SetContent(userControl);

            var windowFrame = (IVsWindowFrame)window.Frame;

            VisualStudio.ErrorHandler.ThrowOnFailure(windowFrame.Show());
        }

        public bool ContextIsOnScreen(object context)
        {
            var targetControl = WndManager.HostedControls.All
                .FirstOrDefault(control => control.DataContext == context);
            if (targetControl == null)
            {
                return false;
            }

            var window = _package.FindToolWindow(typeof(BaseToolWindow),
                                                      Math.Abs(targetControl.GetType().ToString().GetHashCode()),
                                                      true);

            if (window == null || window.Frame == null)
            {
                return false;
            }
            var windowFrame = (IVsWindowFrame)window.Frame;
            int onScreen;
            windowFrame.IsOnScreen(out onScreen);
            return onScreen == 1;
        }
    }
}
